package eTaxi;

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;


public class Bank extends UnicastRemoteObject implements E_Bank {

	private int ride_number;

	private Hashtable accounts = new Hashtable();

	private Hashtable rides = new Hashtable();

	private Hashtable transactions = new Hashtable();

	
	protected Bank() throws RemoteException {
		super();
		ride_number = 0;
	}

	/*
	 * Il metodo regE_Taxi viene invocato da un utente per registrarsi alla
	 * banca; se la banca contiene già un profilo per l'utente, restituisce 0
	 * come codice di errore, 1 altrimenti.
	 */

	public int regE_Taxi(UserProfile u) throws RemoteException {

		if (accounts.containsKey(u.getName()))
			return 0;
		else {
			accounts.put(u.name, u);

			return 1;
		}
	}

	/*
	 * payRide implementa il pagamento della corsa da parte del cliente del
	 * servizio. Il costo viene scalato dal credito nel profilo dell'utente.
	 * Nella tabella hash che registra i pagamenti effettuati, si usa il numero
	 * della prenotazione come indice, e come valore si inserisce un Integer a
	 * 0, che servirà come variabile per contare le chimate al metodo notify.
	 * 
	 * @see eTaxi.E_Bank#payRide(int, int)
	 */

	public int payRide(int Cost, int Number) throws RemoteException {
		Integer ride_number = new Integer(Number);

		UserProfile u = (UserProfile) rides.get(ride_number);
		if (u == null)
			return 0;
		else {
			int old_credit = u.getCredit(); // scalo il costo
			int new_credit = old_credit - Cost;
			u.setCredit(new_credit);
			accounts.put(u.getName(), u);
			Integer acks = new Integer(0);
			transactions.put(ride_number, acks);
			return 1;
		}

	}

	/*
	 * Il metodo check viene usato dai taxi; viene passato come parametro il
	 * nome dello cliente e il tipo di corsa richiesto; restituisce il numero
	 * della prenotazione, 0 se il controllo ha dato esito negativo.
	 */

	public int check(String Name, int Ride) throws RemoteException {

		UserProfile u = (UserProfile) accounts.get(Name);

		if (u == null)
			return 0;
		else {

			int fee = 0;
			switch (Ride) {
			case 1:
				fee = 5;
				break;
			case 2:
				fee = 15;
				break;
			case 3:
				fee = 30;
				break;
			}
			
			if (fee >= u.getCredit())
				return 0;

			else {
				ride_number += 1;
				Integer key = new Integer(ride_number);
				rides.put(key, u);
				return ride_number;

			}

		}
	}

	/*
	 * Con il metodo notify il Cliente ed il Taxi comunicano alla banca l'esito
	 * positivo della transazione. La banca fin tanto che entrambi non hanno
	 * invocato il metodo restituisce 0; prima si controlla se il cliente ha
	 * pagato, in seguito che entrambi abbiano invocato il metodo.
	 */

	public int notify(int Number) throws RemoteException {
		Integer ride_number = new Integer(Number);
		if (transactions.containsKey(ride_number)) {
			Integer aux = (Integer) transactions.get(ride_number);
			int acks = aux.intValue();

			if (acks == 0) {// prima notify
				aux = new Integer(1);
				transactions.put(ride_number, aux);
				return 1;
			} else {
				transactions.remove(ride_number);
				return 1;
			}

		} else { // il cliente non ha ancora pagato
			return 0;
		}
	}

}